home *** CD-ROM | disk | FTP | other *** search
/ TPUG - Toronto PET Users Group / TPUG Users Group CD / TPUG Users Group CD.iso / AMIGA / AMICUS / AMICUS04.ADF / text / autorequester.txt next >
Text File  |  1985-11-16  |  16KB  |  399 lines

  1.  
  2. TITLE:  Deadlock with AutoRequest()
  3.  
  4. WARNING!  We have had several people fall prey to a rather subtle
  5. deadlock situation involving AutoRequest() and (usually) the
  6. MENUVERIFY mode of Intuition.  Other Intuition xVERIFY modes have
  7. similar potential for deadlock as well.
  8.  
  9. AutoRequest() is the Intuition function used to build simple
  10. Requesters -- usually used for error processing.  It blocks the
  11. requesting task until the user responds by selecting an exit
  12. gadget of the requester.  AutoRequest() is built on top of
  13. BuildSysRequest() which, currently, makes a new window and
  14. installs your requester in it.
  15.  
  16. MENUVERIFY is the Intuition menu handling mode which causes Intuition
  17. to send a message to your task if your window is the Active window
  18. and the user presses the Menu button (the right-hand button) on the
  19. mouse.  Intuition will hold off doing all normal interactive
  20. processing until you reply to that message.  Your reply indicates
  21. either that you've done any clean-up processing and Intuition can
  22. go display the menu, or that you want Intuition to ignore this
  23. menu request and let you handle the Right Mouse Button (RMB) yourself
  24. this time.  Your delay before replying should be short because the
  25. system appears hung to the user until you reply to Intuition.
  26.  
  27. You must NOT call AutoRequest() while MENUVERIFY is in effect in any
  28. window controlled by your task.  If you do so, and if your window becomes
  29. the Active window, then if the user presses the Menu button you will be in
  30. a deadlock.  Your task can't procede because the user hasn't selected
  31. an exit gadget on the Requester.  The user can't select that gadget
  32. because Intuition is stuck in MENUVERIFY waiting for your task to reply.
  33. Your task can't reply because it's blocked behind the Requester.
  34.  
  35. The subtlety is that AmigaDOS may generate an AutoRequest() FOR YOU
  36. if an I/O error happens during an AmigaDOS call.
  37.  
  38. If an I/O error occurs during an AmigaDOS I/O call, AmigaDOS looks
  39. at the pr_WindowPtr field of the Process structure for the process
  40. that generated the call.  [An AmigaDOS Process is an EXEC Task plus
  41. a little extra context.  See the dosextens.h or dosextens.i include
  42. files for info.]  If that field is -1, then AmigaDOS returns the
  43. error to the requesting process in the normal fashion.  If that
  44. field is >=0, then AmigaDOS puts up a system requester using the
  45. AutoRequest() facility.  If pr_WindowPtr is 0, that requester is
  46. put up in a new window in the Workbench screen.  If pr_WindowPtr
  47. is positive, then it is interpreted as a pointer to a Window
  48. structure -- usually the control window for your program.  In the
  49. current implementation, AmigaDOS puts up the requester in a new
  50. window in the same screen as the specified window.  Certain unlikely
  51. I/O errors are detected so deeply in the file system that their
  52. requesters can ONLY appear in the Workbench screen even if you
  53. have specified a window.
  54.  
  55. The pr_WindowPtr field is inherited from your process creator.  Normally
  56. it's 0 when your process starts.  If you change the field, you must be
  57. sure to change it back before your program exits.  This is because
  58. you may be running as a co-routine of a CLI in the CLI process context.
  59. If you leave the pointer set to a window that you've just closed, the
  60. CLI will probably crash the system the next time it gets an I/O error.
  61.  
  62. Not all I/O errors will generate requesters.  The ones that do are
  63. the ones that the user can be expected to correct.  These include
  64. Write Protected disks and Wrong Disk in drive.  For more information
  65. on this processing, see the AmigaDOS Technical Reference Manual
  66. chapter on DOS Data Structures.
  67.  
  68. The upshot of all this is that you shouldn't do AmigaDOS I/O calls
  69. while you have MENUVERIFY set and a pr_WindowPtr of other than -1.
  70. If you do, there is a chance that AmigaDOS will be forced to put
  71. up a system requester.  In that case, if the user is so unfortunate
  72. as to hit the Menu button, while your window is the Active window,
  73. you will be in deadlock.
  74.  
  75. Note that if you intend to do ALL your own Right Mouse Button
  76. processing, you can set the RMBTRAP flag in your Window structure
  77. without concern about deadlocks.  The value of the MENUVERIFY stuff
  78. is limited to those cases where you WANT Intuition to do Menu
  79. processing, but you don't want it to do so just now.  For more
  80. information on all of this refer to the manual Intuition:  The
  81. Amiga User Interface.
  82.  
  83.  
  84.  
  85.  
  86.  
  87.       PRELIMINARY INFORMATION... CURRENTLY UNDER REVIEW.
  88.  
  89.       DOESN'T DESCRIBE THE set mouse port FUNCTIONS.
  90.  
  91.       MAY CONTAIN MINOR INACCURACIES IN THE SAMPLE PROGRAM SEGMENT.
  92.  
  93.       (printed version available approx 11/18/85, reviewed and correct-
  94.       ed).
  95.  
  96.       Rob Peck.
  97.  
  98.  
  99.  
  100.  
  101.  
  102.  
  103.                                   Chapter 1
  104.  
  105.  
  106.  
  107.                                 Input Device
  108.  
  109.  
  110.  
  111.  
  112.       This chapter describes the Amiga input device, which is a  combi-
  113.       nation of three other devices:  keyboard device, gameport device,
  114.       and timer device.  The input device merges separate  input  event
  115.       streams from the keyboard, mouse, and timer into a single stream.
  116.       This single stream can then be  interpreted  by  the  prioritized
  117.       linked list of input handlers that are watching the input stream.
  118.  
  119.  
  120.       1.1.  OVERVIEW
  121.  
  122.       The input device is automatically opened by AmigaDOS by any  call
  123.       to  open  the console device.  When the input device is opened, a
  124.       task, appropriately  named  ``input.device'',  is  started.   The
  125.       input  device task communicates directly with the keyboard device
  126.       to obtain raw key inputs.  It also communicates with the gameport
  127.       device  to obtain mouse button and mouse movement events and with
  128.       the timer device to obtain time events.   In  addition  to  these
  129.       event  streams, you can also directly input an event to the input
  130.       device, to be fed to the  handler  chain.   This  topic  is  also
  131.       covered below.
  132.  
  133.       The keyboard device is also accessible directly.  However,  while
  134.       the  input  device task is operating, it attempts to retrieve all
  135.       incoming keyboard events and add them to the input stream.
  136.  
  137.       The gameport device has two units available to it.  As  you  view
  138.       the  Amiga looking at the gameport connectors, connector ``1'' is
  139.       assigned as the primary mouse input for Intuition and contributes
  140.       gameport input events to the input event stream.  Connector ``2''
  141.       is handled by the other gameport  unit  and  is  currently  unas-
  142.       signed.   Each unit of the gameport device is an exclusive access
  143.       object, in that you  can  specify  what  type  of  controller  is
  144.       attached.   It  is  then  assumed  that  only one task is sending
  145.       requests for input from that unit.  While the input  device  task
  146.       is running, that task expects to read the input from connector 1.
  147.       Direct use of the  gameport  device  is  covered  in  a  separate
  148.       chapter of this manual.
  149.  
  150.  
  151.  
  152.  
  153.                               November 13, 1985
  154.  
  155.  
  156.  
  157.  
  158.  
  159.                                     - 2 -
  160.  
  161.  
  162.       The timer device provides time events for the  input  device.  It
  163.       also  provides  time  interval reports for controlling key repeat
  164.       rate and key repeat threshold.  The timer  device  is  a  shared-
  165.       access device and is described in its own separate section.
  166.  
  167.  
  168.       1.2.  INPUT DEVICE COMMANDS
  169.  
  170.       The input device allows the following system functions:
  171.  
  172.  
  173.            box; ci ci l l.
  174.            COMMAND OPERATION
  175.            =
  176.  
  177.            OpenDevice()    Obtain  shared  use  of  the  input  device.
  178.            CloseDevice()   Relinquish   use   of   the   input  device.
  179.            DoIO()  Initiate a command, and wait  for  it  to  complete.
  180.            SendIO()        Initiate  a command, and return immediately.
  181.            AbortIO()       Abort a command already in the queue.
  182.  
  183.  
  184.       Only the Start, Stop,  Invalid,  and  Flush  commands  have  been
  185.       implemented   for  this  device.   All  other  commands  are  no-
  186.       operations.
  187.  
  188.       The input device also supports the following device-specific com-
  189.       mands:
  190.  
  191.                          Table 1-1: Input Device Commands
  192.  
  193.  
  194.            box; ci ci l l.
  195.            I/O COMMAND     OPERATION
  196.            =
  197.  
  198.            IND_WRITEEVENT  Propagate an input event stream to all  dev-
  199.            ices  IND_ADDHANDLER  Add  an  input-stream handler into the
  200.            handler  chain.   IND_REMHANDLER  Remove   an   input-stream
  201.            handler from the handler         chain.  IND_SETTHRESH   Set
  202.            the   repeating   key   hold-down   time    before    repeat
  203.                    starts.   IND_SETPERIOD   Set  the period at which a
  204.            repeating key repeats. IND_SETMPORT    Set the gameport port
  205.            to     which     the     mouse     is             connected.
  206.            IND_SETTRIGGER  Read conditions that must be met by a  mouse
  207.            before          a  pending  read  request will be satisfied.
  208.            IND_SETMTYPE    Set the type of device at the mouse port.
  209.  
  210.  
  211.       The device-specific commands outlined above are described in  the
  212.       following  paragraphs.  A description of the contents of an input
  213.       event is given first because the  input  device  deals  in  input
  214.  
  215.  
  216.                               November 13, 1985
  217.  
  218.  
  219.  
  220.  
  221.  
  222.                                     - 3 -
  223.  
  224.  
  225.       events.  An input event is a data structure that describes:
  226.  
  227.           o   the class of the event-often describes  the  device  that
  228.               generated the event
  229.  
  230.           o   the subclass of the event-space for more  information  if
  231.               needed
  232.  
  233.           o   the  code-keycode  if  keyboard,  button  information  if
  234.               mouse, others
  235.  
  236.           o   a qualifier such as ``ALT key also down'',  ``key  repeat
  237.               active''
  238.  
  239.           o   a position field which contains a data address or a mouse
  240.               position count.
  241.  
  242.           o   a time stamp, showing the sequence in which  events  have
  243.               occurred
  244.  
  245.           o   a link-field by which input events are linked together
  246.  
  247.       The various types of input events are listed in the  include-file
  248.       devices/inputevent.h.   That  information  is  not repeated here.
  249.       You can find more information about input events in the  chapters
  250.       titled ``Gameport Device'' and ``Console Device''.
  251.  
  252.       There is a difference between simply  receiving  an  input  event
  253.       from  a  device  (gameport,  keyboard,  or  console) and actually
  254.       becoming a handler of an input event stream.  A handler is a rou-
  255.       tine  that  is passed an input event, and it is up to the handler
  256.       to decide if it can process the input event.  If the handler does
  257.       not  recognize the event, it passes the address of the event as a
  258.       return value.
  259.  
  260.       Because of the input event field called ie_NextEvent, it is  pos-
  261.       sible for the input event to be a pointer to the first event in a
  262.       linked list of events to be handled.  Thus the handler should  be
  263.       designed  to handle multiple events if such a link is used.  Note
  264.       that handlers can,  themselves,  generate  new  linked  lists  of
  265.       events which can be passed down to lower priority handlers.
  266.  
  267.  
  268.       You add a handler to the chain  by  the  command  IND_ADDHANDLER.
  269.       Assuming  that  you have a properly initialized an IOStdReq block
  270.       as a result of a call to OpenDevice()  (for  the  input  device),
  271.       here is a typical C-language call to the IND_ADDHANDLER function:
  272.  
  273.  
  274.  
  275.  
  276.  
  277.  
  278.  
  279.  
  280.  
  281.  
  282.                               November 13, 1985
  283.  
  284.  
  285.  
  286.  
  287.  
  288.                                     - 4 -
  289.  
  290.  
  291.  
  292.               struct Interrupt handlerStuff;
  293.               handlerStuff.is_Data = &hsData;
  294.                               /* address of its data area */
  295.               handlerStuff.is_Code = myhandler;
  296.                               /* address of entry point to handler */
  297.               handlerStuff.is_Node.ln_Pri = 51;
  298.                               /* set the priority one step higher than
  299.                                * Intution, so that our handler enters
  300.                                * the chain ahead of Intuition.
  301.                                */
  302.               inputRequestBlock.io_Command = IND_ADDHANDLER;
  303.               inputRequestBlock.io_Data = &handlerStuff;
  304.  
  305.               DoIO(&inputRequestBlock);
  306.  
  307.  
  308.       Notice from the above that Intuition is one of the  input  device
  309.       handlers  and  normally  distributes  all  of  the  input events.
  310.       Intuition inserts itself at priority position 50.  You can choose
  311.       the  position in the chain at which your handler will be inserted
  312.       by setting the priority field in the list-node part of the inter-
  313.       rupt data structure you are feeding to this routine.
  314.  
  315.       Note also that any processing time expended  by  a  handler  sub-
  316.       tracts  from  the  time  available before the next event happens.
  317.       Therefore, handlers for the input stream must be fast.
  318.  
  319.  
  320.  
  321.                        Rules for Input Device Handlers
  322.  
  323.       The following rules should be followed when you are designing  an
  324.       input handler:
  325.  
  326.           1.  If an input handler is capable of processing  a  specific
  327.               kind  of  an  input  event  and  that  event has no links
  328.               (ie_NextEvent = 0), the handler can end the handler chain
  329.               by returning a NULL (0) value.
  330.  
  331.           2.  If there are multiple events linked together, the handler
  332.               can  feel  free  to  delink an event from the input event
  333.               chain, thereby passing a shorter list of events to subse-
  334.               quent  handlers.   The  starting  address of the modified
  335.               list is the return value.
  336.  
  337.           3.  If a handler wishes to add new events to the  chain  that
  338.               it  passes to a lower priority handler, it may initialize
  339.               memory to contain the new  event  or  event  chain.   The
  340.               handler,  when it again gets control on the next round of
  341.               event handling, should assume nothing about  the  current
  342.               contents  of  the  memory blocks it attached to the event
  343.               chain.  Lower priority handlers  may  have  modified  the
  344.  
  345.  
  346.  
  347.                               November 13, 1985
  348.  
  349.  
  350.  
  351.  
  352.  
  353.                                     - 5 -
  354.  
  355.  
  356.               memory  as  they  handled  their  part  of the event. The
  357.               handler that allocates the memory for this purpose should
  358.               keep  track  of the starting address and the size of this
  359.               memory chunk so that the memory can be  returned  to  the
  360.               free memory list when it is no longer needed.
  361.  
  362.       Your routine should be structured so that it  can  be  called  as
  363.       though from the following assembler language statement:
  364.  
  365.               newEventChain = yourHandlerCode(oldEventChain, yourHandlerData);
  366.  
  367.       where:
  368.  
  369.           o   yourHandlerCode is the entry point to your routine,
  370.  
  371.           o   oldEventChain is the starting  address  for  the  current
  372.               chain of input events, and
  373.  
  374.           o   newEventChain is the starting address of an  event  chain
  375.               which you are passing to the next handler, if any.
  376.  
  377.       A NULL (0) value terminates the handling.
  378.  
  379.       Memory that you use to describe a new  input  event  that  you've
  380.       added  to the event chain is available for re-use or deallocation
  381.       when the handler is called again or after the IND_REMHANDLER com-
  382.       mand for the handler is complete.
  383.  
  384.       Because IND_ADDHANDLER installs a handler in any position in  the
  385.       handler  chain,  it  can,  for  example, ignore specific types of
  386.       input events as well as act upon and modify existing  streams  of
  387.       input.   It  can  even  create  new input events for Intuition or
  388.       other programs to interpret.
  389.  
  390.  
  391.       You remove a handler from the  handler  chain  with  the  command
  392.       IND_REMHANDLER.   Assuming  that  you have a properly initialized
  393.       IOStdReq block as a result of a call  to  OpenDevice()  (for  the
  394.       input  device)  and  you  have  already  added  the handler using
  395.       IND_ADDHANDLER,  here  is  a  typical  C-language  call  to   the
  396.       IND_REMHANDLER function:
  397.  
  398.               inputRequestBlock.io_Command = IND_REMHANDLER;
  399.               inputRequestBlock.io_Da